import React, { useCallback, useState, useContext, useEffect } from 'react';
import { usePlugin, RenderDropableWidget, TextWidget } from '@inbiz/react';
import { Field } from '@formily/core';
import { uuid } from '@inbiz/utils';
import SearchTag from './SearchTag';
import PackUp from './components/Icon/Packup';
import Develop from './components/Icon/Develop';
import { objIsNotEmpty } from '../../shared';
import { InBizTableCtx, InBizTableRefCtx } from '../../context';
import formatters from '../../formatters';
import { getTableStorage, setTableStorage, useColumnConfig, useIsDesigner } from '../../hooks';
import { SearchProps } from '../../interfaces';

let timer: any = null;
let inSearchRegion: boolean = false;

const Search = (props: SearchProps) => {
  // 生成一个8位数的唯一标识，防止一个页面多个表格监听错乱
  const identification = `table${uuid(8, 16)}`;
  const isDesignable = useIsDesigner();
  const { queryFields } = useColumnConfig();
  const { searchRef } = useContext(InBizTableRefCtx);
  const { search } = useContext(InBizTableCtx);
  const { inbiz, controlId, saveSearch } = useContext(InBizTableCtx);
  const [packUp, setPackUp] = useState(false);

  let queryPlugin: any;
  if (isDesignable) {
    queryPlugin = usePlugin('Table.Query');
  }

  const getSearchValues = () => {
    const values = {};
    (inbiz as any)?.getFields?.(controlId)?.forEach((field: Field) => {
      if (field.hasOwnProperty('value') && field?.componentProps?.tablequeryfield) {
        // 成员选择查询时需要格式化查询数据
        values[field?.componentProps?.tablequeryfield] = {
          value:
            field?.componentType === 'EformMemberSelect'
              ? field?.value?.map((value: any) =>
                formatters.formatMemberSelectValue(value, field?.componentProps?.tabs),
              )
              : field?.value,
          type: field?.componentType,
          name: field.props.name,
        };
      }
    });
    const initParams = searchRef.current.initParams;
    const searchValues =
      objIsNotEmpty(values) && queryFields
        ? formatters.getQueryGroups(queryFields, values, initParams)
        : [];
    searchRef.current = {
      ...searchRef.current,
      pageInfo: {
        ...searchRef.current.pageInfo!,
        current: 1,
      },
      conditions: searchValues,
      iConditions: {
        ...searchRef.current.iConditions,
        pageIndex: 1
      }
    };
    return searchValues;
  };

  const onSearch = useCallback(() => {
    (inbiz as any)
      ?.validate?.(controlId)
      ?.then(() => {
        getSearchValues();
        props.fetchData();
      })
      .catch((err: any) => console.log('search-valid', err));
  }, []);

  // 回车查询数据
  const searchData = () => {
    if (timer) {
      clearTimeout(timer);
      timer = null;
    }
    timer = setTimeout(() => {
      onSearch();
    }, 500);
  };

  // 鼠标焦点在查询区域内时，回车查询数据
  const inSearchRegionGetData = (e: any) => {
    if (e.key == 'Enter') {
      searchData();
    }
  };

  // 鼠标焦点在查询区域外并且查询控件是选中时，回车查询数据
  const outSearchRegionGetData = (e: any) => {
    if (e.key === 'Enter') {
      const isActiveField = (inbiz as any)
        ?.getFields?.(controlId)
        ?.some((field: Field) => field.active);
      if (isActiveField && !inSearchRegion) {
        searchData();
      }
    }
  };

  // 鼠标移入查询区域事件
  const mouseEnterEvent = () => {
    inSearchRegion = true;
    document.addEventListener('keydown', inSearchRegionGetData);
  };

  // 鼠标移出查询区域事件
  const mouseLeaveEvent = () => {
    inSearchRegion = false;
    document.removeEventListener('keydown', inSearchRegionGetData);
  };

  // 标签区域展开、收起事件
  const onPackUpChange = useCallback((value: boolean) => {
    setTableStorage({
      inbiz,
      controlId,
      tableTagStatus: value ? 'packUp' : 'develop',
    });
    setPackUp(value)
  }, [])

  useEffect(() => {
    const searchDom = document.querySelector(
      `.inbiz-table-search.${identification} .search-container`,
    );
    const storage = getTableStorage()
    if (storage && !isDesignable) {
      const userId = inbiz?.appInfo?.userInfo.guid;
      const currentPage = inbiz?.pageId;
      if (storage[userId] && storage[userId][currentPage] && storage[userId][currentPage][controlId]) {
        const isPackUp = storage[userId][currentPage][controlId]?.tagStatus == 'packUp' ? true : false
        setPackUp(isPackUp);
      }
    }
    searchDom?.addEventListener('mouseenter', mouseEnterEvent);
    searchDom?.addEventListener('mouseleave', mouseLeaveEvent);
    document.addEventListener('keydown', outSearchRegionGetData);
    return () => {
      searchDom?.removeEventListener('mouseenter', mouseEnterEvent);
      searchDom?.removeEventListener('mouseleave', mouseLeaveEvent);
      document.removeEventListener('keydown', outSearchRegionGetData);
    };
  }, []);

  return search ? (
    <div className={`inbiz-table-search ${identification}`}>
      {isDesignable ? (
        <div className="search-container">
          <RenderDropableWidget node={queryPlugin} pluginName={'Table.Query'} />
        </div>
      ) : (
        <>
          <div className="search-container">
            <RenderDropableWidget pluginName={'Table.Query'} />
          </div>
          {saveSearch && (
            <div className="search-tag-container">
              {!packUp ? (
                <>
                  <PackUp onClick={() => onPackUpChange(true)} />
                  <div className="search-tag-cut-line"></div>
                </>
              ) : (
                <Develop onClick={() => onPackUpChange(false)} />
              )}
              <div className={packUp ? 'search-tag-box-packup' : 'search-tag-box'}>
                <span className="tag-titie">
                  <TextWidget>Table.saveSearch</TextWidget>
                </span>
                <SearchTag fetchData={props.fetchData} />
              </div>
            </div>
          )}
        </>
      )}
    </div>
  ) : null;
};

export default React.memo(Search);
